home *** CD-ROM | disk | FTP | other *** search
- #include "../../../include/kpstdlib.h"
- #include "../../../include/wd_kp.h"
- #include "../kptest_com.h"
-
-
- BOOL __cdecl KP_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext);
- void __cdecl KP_Close(PVOID pDrvContext);
- void __cdecl KP_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode);
- BOOL __cdecl KP_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext);
- void __cdecl KP_IntDisable(PVOID pIntContext);
- BOOL __cdecl KP_IntAtIrql(PVOID pIntContext, BOOL *fIsMyInterrupt);
- DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount);
-
- BOOL __cdecl KP_Init(KP_INIT *kpInit)
- {
- // check if the version of WD_KP.LIB is the same version as WINDRVR.H and WD_KP.H
- if (kpInit->dwVerWD!=WD_VER)
- {
- // you need to re-compile your kernel plugin with the compatible version of WD_KP.LIB, WINDRVR.H and WD_KP.H!
- return FALSE;
- }
-
- kpInit->funcOpen = KP_Open;
- strcpy (kpInit->cDriverName, "KPTEST"); // until 8 chars
-
- return TRUE;
- }
-
- // called when WD_KernelPlugInOpen() is called. pDrvContext returned will be passed to
- // rest of the functions
- BOOL __cdecl KP_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext)
- {
- kpOpenCall->funcClose = KP_Close;
- kpOpenCall->funcCall = KP_Call;
- kpOpenCall->funcIntEnable = KP_IntEnable;
- kpOpenCall->funcIntDisable = KP_IntDisable;
- kpOpenCall->funcIntAtIrql = KP_IntAtIrql;
- kpOpenCall->funcIntAtDpc = KP_IntAtDpc;
-
- *ppDrvContext = NULL; // you can allocate memory here
-
- return TRUE;
- }
-
- // called when WD_KernelPlugInClose() is called
- void __cdecl KP_Close(PVOID pDrvContext)
- {
- // you can free the memory allocated to pDrvContext here
- }
-
- // called when WD_KernelPlugInCall() is called
- void __cdecl KP_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode)
- {
- kpCall->dwResult = KPTEST_OK;
-
- switch ( kpCall->dwMessage )
- {
- case KPTEST_MSG_VERSION: // in this sample we implement a GetVersion message
- {
- DWORD dwVer = 100;
- KPTEST_VERSION *ver = (KPTEST_VERSION *) kpCall->pData;
- COPY_TO_USER_OR_KERNEL(&ver->dwVer, &dwVer, sizeof(DWORD), fIsKernelMode);
- COPY_TO_USER_OR_KERNEL(ver->cVer, "My Driver V1.00", sizeof("My Driver V1.00")+1, fIsKernelMode);
- kpCall->dwResult = KPTEST_OK;
- }
- break ;
- // you can implement other messages here
- default:
- kpCall->dwResult = KPTEST_NO_IMPL_MESSAGE;
- }
- }
-
- // called when WD_IntEnable() is called, with a kernel plugin handler specified
- // the pIntContext will be passed to the rest of the functions handling interrupts.
- // returns TRUE if enable is succesful
- BOOL __cdecl KP_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext)
- {
- DWORD *pIntCount;
-
- // you can allocate memory specific for each interrupt in *ppIntContext
- *ppIntContext = malloc(sizeof (DWORD));
- if (!*ppIntContext)
- return FALSE;
- // in this sample the information is a DWORD used to count the incomming interrupts
- pIntCount = (DWORD *) *ppIntContext;
- *pIntCount = 0; // reset the count to zero
-
- return TRUE;
- }
-
- // called when WD_IntDisable() is called
- void __cdecl KP_IntDisable(PVOID pIntContext)
- {
- // you can free the interrupt specific memory to pIntContext here
- free(pIntContext);
- }
-
- // returns TRUE if needs DPC.
- // this function is called at IRQL level - at physical interrupt handler.
- // most library calls are NOT allowed, for example:
- // NO WD_xxxx() calls, except WD_Transfer(),
- // NO malloc,
- // NO free
- // YES WD_Transfer
- // YES your functions, as long as they dont call library functions
- // YES specific kernel functions, that the Win DDK specifically allows them to be
- // called at IRQL
- BOOL __cdecl KP_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt)
- {
- DWORD *pdwIntCount = (DWORD *) pIntContext;
-
- // you should check your hardware here to see if the interrupt belongs to you.
- // if in doubt, return FALSE (this is the safest)
- *pfIsMyInterrupt = FALSE;
-
- // in this example we will schedule a DPC once in every 5 interrupts
- (*pdwIntCount) ++;
- if (*pdwIntCount==5)
- {
- *pdwIntCount = 0;
- return TRUE;
- }
-
- return FALSE;
- }
-
- // returns the number of times to notify user-mode (i.e. return from WD_IntWait)
- DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount)
- {
- return dwCount; // return WD_IntWait as many times as KP_IntAtIrql scheduled KP_IntAtDpc()
- }
-
-
-